package com.sg.plugin.obff.interceptor;

import com.alibaba.fastjson.JSON;
import com.wicket.okrobff.common.baseinfo.AuthContext;
import com.wicket.okrobff.common.baseinfo.BaseInfoDO;
import com.wicket.okrobff.common.baseinfo.BaseInfoHolder;
import com.wicket.okrobff.common.domain.redis.PublicInfoForRedis;
import com.wicket.okrobff.common.exception.BizException;
import com.sg.common.ro.OkrResult;
import com.wicket.okrobff.common.tools.StringUtils;
import com.sg.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;


/**
 * @author ：CHS
 * @version 1.0
 * @since 2022/5/7 17:55
 */
@Component
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {


        // 假设从header中取值
        String token = request.getHeader("X-Auth-Token");
        if (StringUtils.isEmpty(token)) {
            writeError2Response(response, "还未登录");
            return false;
        }
        String commonInfoStr = (String) redisUtil.get("登录令牌" + ":" + token);
        if (commonInfoStr == null) {
            //writeError2Response(response, "登录失效，请重新登录");
            throw new BizException("403", "登录失效，请重新登录", false);
        }
        PublicInfoForRedis publicInfo = JSON.parseObject(commonInfoStr, PublicInfoForRedis.class);

        // 判断是否重新登录
        String loginTokenKey = "token-" + publicInfo.getOriginalRoleMemberId();
        String lastToken = (String) redisUtil.get("登录令牌" + ":" + loginTokenKey);
        if (StringUtils.isEmpty(lastToken)) {
            throw new BizException("403", "登录失效，请重新登录", false);
        }
        if (!lastToken.equals(token)) {
            // writeError2Response(response, "账号异地登录，您已下线");
            //return false;
        }

        String loginIp = "127.0.0.1";
        String referer = request.getHeader("Referer");
        if (referer != null && !referer.isEmpty()) {
            java.net.URL url = new java.net.URL(referer);
            String host = url.getHost();
            loginIp = host;
        }

        String source = "PC";
        String authSource = request.getHeader("X-Auth-Souce");
        if (authSource != null && !authSource.isEmpty()) {
            source = authSource;
        }

        if (BaseInfoHolder.contextHolder.get() != null) {
            AuthContext authContext = BaseInfoHolder.contextHolder.get();
            BaseInfoDO baseInfoDO = authContext.getBaseInfo();
            baseInfoDO.setSpecAppId(publicInfo.getAppId());
            baseInfoDO.setSpecInductionRecordId(publicInfo.getInductionRecordId());
            baseInfoDO.setSpecOriginalRoleMemberId(publicInfo.getOriginalRoleMemberId());
            baseInfoDO.setSpecSpaceId(publicInfo.getSpaceId());
            baseInfoDO.setSpecSceneId(publicInfo.getSceneId());
            baseInfoDO.setSpecUserId(publicInfo.getUserId());
            baseInfoDO.setSpecLoginIp(loginIp);
            baseInfoDO.setSpecDeptId(publicInfo.getDeptId());
            baseInfoDO.setSpecRoleCode(publicInfo.getRoleCode());
            baseInfoDO.setSpecSource(source);
            baseInfoDO.setSpecHighestOrgID(publicInfo.getHighestOrgID());
            baseInfoDO.setSpecOrganizationId(publicInfo.getOrganizationId());
        } else {
            BaseInfoDO baseInfoDO = new BaseInfoDO();
            baseInfoDO.setSpecAppId(publicInfo.getAppId());
            baseInfoDO.setSpecInductionRecordId(publicInfo.getInductionRecordId());
            baseInfoDO.setSpecOriginalRoleMemberId(publicInfo.getOriginalRoleMemberId());
            baseInfoDO.setSpecSpaceId(publicInfo.getSpaceId());
            baseInfoDO.setSpecSceneId(publicInfo.getSceneId());
            baseInfoDO.setSpecUserId(publicInfo.getUserId());
            baseInfoDO.setSpecDeptId(publicInfo.getDeptId());
            baseInfoDO.setSpecLoginIp(loginIp);
            baseInfoDO.setSpecRoleCode(publicInfo.getRoleCode());
            baseInfoDO.setSpecSource(source);
            baseInfoDO.setSpecHighestOrgID(publicInfo.getHighestOrgID());
            baseInfoDO.setSpecOrganizationId(publicInfo.getOrganizationId());
            AuthContext authContext = new AuthContext();
            authContext.setBaseInfo(baseInfoDO);
            BaseInfoHolder.contextHolder.set(authContext);
        }


        return true;


    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception e) throws Exception {

        BaseInfoHolder.contextHolder.remove();
    }

    private void writeError2Response(HttpServletResponse response, String message) {
        try {
            OkrResult<String> notAuthorityResult = OkrResult.fail("0", message);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(notAuthorityResult));
            writer.close();
        } catch (IOException e) {
            log.error("响应消息写入失败.", e);
        }
    }
}
